¿Qué hice mal aquí? Recibo "Error [ERR_HTTP_HEADERS_SENT]: no se pueden establecer encabezados después de enviarlos al cliente NodeJS", ¿alguien puede ayudarme?
Estoy usando:
Expresar mangosta (para MongoDB)
Controlador
export const postResetPasswordEmail: Controller = async (req: Request, res: Response, next: NextFunction): Promise<void> => { const { email } = req.body try { const errors: IValidatorError = getValidationErrors(req) if (Object.keys(errors).length !== 0) { res.status(403).json({ errors }) return } const user = await User.findOne({ email }) if (!user) { res.status(404).json({ message: AuthenticationErrors.noEmailFound }) return } else { if (!(user.passwordUpdatedAt === undefined || (new Date(user.passwordUpdatedAt) < new Date()))) { res.status(404).json({ message: AuthenticationErrors.error10MinutesPassword }) return } } const token = generateJWT({ email }, JWTKEY, '10m') await sendResetPasswordMail(email, token, next) res.status(200) .json({ message: SuccessMessages.resetPassword }) } catch (err: any) { catchError(err, next) } }enviarResetPasswordMail
const sendResetPasswordMail: SendResetPasswordMail = async (userEmail: string, token: string, next: NextFunction): Promise<void> => { try { const transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: adminEmail.email, pass: adminEmail.pass } }) const mailOptions = { from: adminEmail.email, to: userEmail, subject: 'Reset password', text: `Reset password: http://localhost:3000/resetPassword?token=${token}` } await transporter.sendMail(mailOptions) } catch (err: any) { catchError(err, next) } }generarJWT
const generateJWT: GenerateJWT = (userInfo: IUserInfo, JWTKEY: string, expireTime: string): string => jwt.sign({ ...userInfo }, JWTKEY, { expiresIn: expireTime })Veo una falla en sendResetPasswordMail : supongamos que tiene una excepción allí y llama a catchError dentro del bloque catch de sendResetPasswordMail , en este caso llamará indirectamente a next , que a su vez llamaría a res.status().send() dentro del controlador de errores expreso predeterminado .
Sin embargo, a pesar de la excepción, sendResetPasswordMail devolverá el control a su controlador, que intentará enviar el estado 200 después de eso, y si para ese momento el controlador de errores ya envió la respuesta, obtendrá el error.
El comportamiento válido sería no capturar excepciones dentro de sendResetPasswordMail y dejarlo en manos de la persona que llama. Y también puede eliminar el siguiente parámetro de sendResetPasswordMail